local cos = math.cos
local sin = math.sin
local flip_core = flip_core

module "flip"

local vert_buffer = {}
local vert_n = 1
local col_n = 1
local color_buffer = {}
local texcoord_buffer = {}
local geom_mode = -1
local cur_tex = nil
local is_colored = false

local g_quad = 0
local g_line = 1
local g_trifan = 2
local g_linestrip = 3
local g_tri = 4
local g_point = 5
local g_image = 6

local colr, colg, colb, cola = 1, 1, 1, 1

local function lua_test_vertex_color(count)
	if is_colored then
		for i=1,count do
			color_buffer[col_n] = colr
			color_buffer[col_n + 1] = colg
			color_buffer[col_n + 2] = colb
			color_buffer[col_n + 3] = cola

			col_n = col_n + 4
		end
	end
end

-- NOTE: Destroying sprites while they are pending in the
-- geometry buffer may cause graphical artifacts.
function flush_geometry()
	if vert_n <= 1 then
		return
	end

	flip_core.lua_test_flush_buffers(
		geom_mode,
		vert_buffer,
		texcoord_buffer,
		color_buffer,
		vert_n - 1,
		cur_tex,
		colr, colg, colb, cola,
		is_colored)
	vert_n = 1
	col_n = 1
	is_colored = false
end

local function lua_test_clear()
	flush_geometry()
	vert_n = 1
	col_n = 1
end

function color(r, g, b, a)
	if colr ~= r or colg ~= g or colb ~= b or cola ~= a then
		-- vert_n > 1
		colr = r
		colg = g
		colb = b
		cola = a
	end
end

function begin_sprites_2()
	if geom_mode ~= g_image then
		geom_mode = g_image
		lua_test_clear()
	end
end

function sprite_centered_2(sprite, x, y)
	local w = sprite.w
	local h = sprite.h
	local halfw = w*0.5
	local halfh = h*0.5

	local tex = sprite.tex
	if not tex then
		sprite:upload()
		tex = sprite.tex
	end

	if cur_tex ~= tex then
		flush_geometry()
		cur_tex = tex
	end

	local lvert_n = vert_n

	if lvert_n > 4096-8 then
		flush_geometry()
		lvert_n = 1
	end

	local ltexcoord_buffer = texcoord_buffer
	local lvert_buffer = vert_buffer

	ltexcoord_buffer[lvert_n] = sprite[2]
	ltexcoord_buffer[lvert_n + 1] = sprite[3]
	ltexcoord_buffer[lvert_n + 2] = sprite[4]
	ltexcoord_buffer[lvert_n + 3] = sprite[5]
	ltexcoord_buffer[lvert_n + 4] = sprite[6]
	ltexcoord_buffer[lvert_n + 5] = sprite[7]
	ltexcoord_buffer[lvert_n + 6] = sprite[8]
	ltexcoord_buffer[lvert_n + 7] = sprite[9]

	lua_test_vertex_color(4)

	local x1 = x - halfw
	local x2 = x + halfw
	local y1 = y - halfh
	local y2 = y + halfh

	lvert_buffer[lvert_n] = x1
	lvert_buffer[lvert_n + 1] = y1
	lvert_buffer[lvert_n + 2] = x2
	lvert_buffer[lvert_n + 3] = y1
	lvert_buffer[lvert_n + 4] = x2
	lvert_buffer[lvert_n + 5] = y2
	lvert_buffer[lvert_n + 6] = x1
	lvert_buffer[lvert_n + 7] = y2

	vert_n = lvert_n + 8
end

function sprite_centered_rot(sprite, x, y, ang)
	local w = sprite.w
	local h = sprite.h
	local halfw = w*0.5
	local halfh = h*0.5

	local ax, ay = cos(ang), sin(ang)

	local x1 = halfw*ax
	local y1 = halfw*ay

	local x2 = halfh*ay
	local y2 = halfh*ax

	local xul = x2 - x1
	local xur = x1 + x2
	local ylr = y1 + y2
	local yur = y1 - y2

	local tex = sprite.tex
	if not tex then
		sprite:upload()
		tex = sprite.tex
	end

	if cur_tex ~= tex then
		flush_geometry()
		cur_tex = tex
	end

	local lvert_n = vert_n

	if lvert_n > 4096-8 then
		flush_geometry()
		lvert_n = 1
	end

	local ltexcoord_buffer = texcoord_buffer
	local lvert_buffer = vert_buffer

	ltexcoord_buffer[lvert_n] = sprite[2]
	ltexcoord_buffer[lvert_n + 1] = sprite[3]
	ltexcoord_buffer[lvert_n + 2] = sprite[4]
	ltexcoord_buffer[lvert_n + 3] = sprite[5]
	ltexcoord_buffer[lvert_n + 4] = sprite[6]
	ltexcoord_buffer[lvert_n + 5] = sprite[7]
	ltexcoord_buffer[lvert_n + 6] = sprite[8]
	ltexcoord_buffer[lvert_n + 7] = sprite[9]

	lua_test_vertex_color(4)

	lvert_buffer[lvert_n] = x + xul
	lvert_buffer[lvert_n + 1] = y - ylr
	lvert_buffer[lvert_n + 2] = x + xur
	lvert_buffer[lvert_n + 3] = y + yur
	lvert_buffer[lvert_n + 4] = x - xul
	lvert_buffer[lvert_n + 5] = y + ylr
	lvert_buffer[lvert_n + 6] = x - xur
	lvert_buffer[lvert_n + 7] = y - yur

	vert_n = lvert_n + 8
end